<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 7/17/17
 * Time: 1:43 PM
 */

namespace api\modules\unionpay\controllers;

use common\components\tools\Tools;
use common\components\unionpay\Config;
use common\components\unionpay\SecssUtil;
use common\components\unionpay\Unionpay;
use common\models\credit_app\Order;
use common\models\credit_public\SlCheck;
use common\models\credit_public\SlCheck1004;
use common\models\credit_public\SlCheck1009;
use common\models\credit_public\SlCheck1022;
use common\models\credit_public\SlCheck1025;
use common\models\Unionpay3002SetLog;
use wodrow\yii\rest\Controller;
use yii\base\ErrorException;
use yii\httpclient\Client;

/**
 * 认证业务
 * Class BusinessController
 * @package api\modules\unionpay\controllers
 */
class BusinessController extends Controller
{
    /**
     * 卡无密五要素认证
     * @desc 《业务编号：1003（卡无密五要素认证（有手机号））》 功能描述：主要为卡无密五要素认证（卡号，证件类型[身份证]，证件号，姓名，银行预留手机号）
     * 交易方式：支持后台接入，前台接入，SDK接入。
     * @param string $mobile 手机号
     * @param string $usrName 证件姓名
     * @param string $cardNo 证件号
     * @param string $certNo 卡号[身份证]
     * @param string $cardPhone 卡关联手机号
     */
    public function actionCardNo5($mobile, $usrName, $cardNo, $certNo, $cardPhone)
    {
        /*$params = [
            'mobile' => '15150001117',
            'dcType' => '0', // 借贷标志
            'certType' => '01', // 证件类型
            'usrName' => '杨松霖', // 证件姓名
            'sensData' => [
                'cardNo' => "6217001250002395063", // 卡号
                'certNo' => "320311198806185531", // 证件号
                'cardPhone' => "15150001117", // 卡  关联手机号
            ]
        ];*/
        $sl_check = SlCheck::findOne(['c_name'=>$usrName, 'c_tel'=>$mobile, 'c_card'=>$certNo, 'c_bankcard'=>$cardNo]);
        if ($sl_check){
            if (time()-$sl_check->c_time>3600*24*30||$sl_check->c_source!=$sl_check::SOURCE_UNIONPAY||YII_ENV_DEV){
                $sl_check->c_time = time();
                $sl_check->c_source = $sl_check::SOURCE_UNIONPAY;
            }else{
                return [
                    'sl_check' => $sl_check->toArray(),
                ];
            }
        }else{
            $sl_check = new SlCheck();
            $sl_check->c_name = $usrName;
            $sl_check->c_tel = $mobile;
            $sl_check->c_card = $certNo;
            $sl_check->c_bankcard = $cardNo;
            $sl_check->c_source = $sl_check::SOURCE_UNIONPAY;
            $sl_check->c_time = time();
        }
        $unionpay = new Unionpay();
        $r = $unionpay->send(Config::$b_url, [
            'mobile' => $mobile,
            'dcType' => '0', // 借贷标志
            'certType' => '01', // 证件类型
            'usrName' => $usrName, // 证件姓名
            'sensData' => [
                'cardNo' => $cardNo, // 卡号
                'certNo' => $certNo, // 证件号
                'cardPhone' => $cardPhone, // 卡关联手机号
            ], // 敏感域
        ], ['busiType'=>'1003']);
        $sl_check->c_issame = $r['_respData']['respMsg'];
        if ($sl_check->save()){}else{
            throw new ErrorException("保存失败", 1063);
        }
        $_r = array_merge(['sl_check' => $sl_check->toArray()], $r);
        return $_r;
        /*if (isset($r['_respData']['respCode'])&&$r['_respData']['respCode']=='000000000'){
            return $r;
        }else{
            return $r;
        }*/
    }

    /**
     * 卡无密四要素认证
     * @desc 《业务编号：1004（卡无密四要素认证（无手机号））》 功能描述：主要为卡无密四要素认证（卡号，证件类型[身份证]，证件号，姓名）
     * @param string $mobile 手机号
     * @param string $usrName 证件姓名
     * @param string $cardNo 证件号
     * @param string $certNo 卡号[身份证]
     */
    public function actionCardNo4($usrName, $cardNo, $certNo)
    {
        /*$params = [
            'dcType' => '0', // 借贷标志
            'certType' => '01', // 证件类型
            'usrName' => '杨松霖', // 证件姓名
            'sensData' => [
                'cardNo' => "6217001250002395063", // 卡号
                'certNo' => "320311198806185531", // 证件号
            ]
        ];*/
        if ($usrName){}else{
            throw new ErrorException('usrName不能为空', 1079);
        }
        if ($cardNo){}else{
            throw new ErrorException('cardNo不能为空', 1080);
        }
        if ($certNo){}else{
            throw new ErrorException('certNo不能为空', 1080);
        }
        $sl_check_1004 = SlCheck1004::findOne(['c_name'=>$usrName, 'c_card'=>$certNo, 'c_bankcard'=>$cardNo]);
        if ($sl_check_1004){
            if (time()-$sl_check_1004->c_time>3600*24*30||$sl_check_1004->c_source!=$sl_check_1004::SOURCE_UNIONPAY||$sl_check_1004->c_issame!='认证/查询成功'){
                $sl_check_1004->c_time = time();
                $sl_check_1004->c_source = $sl_check_1004::SOURCE_UNIONPAY;
            }else{
                return [
                    'sl_check_1004' => $sl_check_1004->toArray(),
                ];
            }
        }else{
            $sl_check_1004 = new SlCheck1004();
            $sl_check_1004->c_name = $usrName;
            $sl_check_1004->c_card = $certNo;
            $sl_check_1004->c_bankcard = $cardNo;
            $sl_check_1004->c_source = $sl_check_1004::SOURCE_UNIONPAY;
            $sl_check_1004->c_time = time();
        }
        $unionpay = new Unionpay();
        $r = $unionpay->send(Config::$b_url, [
            'dcType' => '0', // 借贷标志
            'certType' => '01', // 证件类型
            'usrName' => $usrName, // 证件姓名
//            'orderId' => Config::$merchant_id.date("YmdHis").rand(100,999),
//            'orderDate' => date("Ymd"),
            'sensData' => [
                'cardNo' => $cardNo, // 卡号
                'certNo' => $certNo, // 证件号
            ], // 敏感域
        ], ['busiType'=>'1004']);
        $sl_check_1004->c_issame = $r['_respData']['respMsg'];
        $sl_check_1004->c_orderid = $r['_respData']['orderId'];
        $sl_check_1004->c_post = $r['_respData']['c_post'];
        $sl_check_1004->c_back = $r['_respData']['c_back'];
        if ($sl_check_1004->save()){}else{
            throw new ErrorException("保存失败".var_export($sl_check_1004->getErrors(), true), 1064);
        }
        $_r = array_merge(['sl_check' => $sl_check_1004->toArray()], $r);
        return $_r;
    }

    /**
     * 公民身份验证-中文-含照片无地址
     * @desc 《业务编号：1022（公民身份验证-中文-含照片无地址）》 功能描述：主要为验证，身份证号和证件中文姓名是否一致，返回照片。
     * @param string $usrName 证件姓名
     * @param string $certNo 卡号[身份证]
     */
    public function actionIdenVerify($usrName, $certNo)
    {
        /*$params = [
            'usrName' => '杨松霖', // 中文姓名
            'sensData' => [
                'certNo' => "320311198806185531", // 证件号
            ]
        ];*/
        $sl_check = SlCheck1022::findOne(['c_name'=>$usrName, 'c_card'=>$certNo]);
        if ($sl_check){
            if (time()-$sl_check->c_time>3600*24*30||$sl_check->c_source!=$sl_check::SOURCE_UNIONPAY||$sl_check->perfer_back!='认证/查询成功'){
                $sl_check->c_time = time();
                $sl_check->c_source = $sl_check::SOURCE_UNIONPAY;
            }else{
                return [
                    'sl_check_1022' => $sl_check->toArray(),
                ];
            }
        }else{
            $sl_check = new SlCheck1022();
            $sl_check->c_name = $usrName;
            $sl_check->c_card = $certNo;
            $sl_check->c_source = $sl_check::SOURCE_UNIONPAY;
            $sl_check->c_time = time();
        }
        $unionpay = new Unionpay();
        $r = $unionpay->send(Config::$b_url, [
            'usrName' => $usrName, // 证件姓名
            'sensData' => [
                'certNo' => $certNo, // 证件号
            ], // 敏感域
        ], ['busiType'=>'1022']);
        $sl_check->perfer_back = $r['_respData']['respMsg'];
        if ($sl_check->save()){}else{
//            return $sl_check->getErrors();
            throw new ErrorException("保存失败", 1065);
        }
        $_r = array_merge(['sl_check_1022' => $sl_check->toArray()], $r);
        return $_r;
    }

    /**
     * 运营商三要素验证
     * @desc 3.2.3《业务编号：1025（运营商三要素验证(三要素认证：姓名+身份证+手机号)）》功能描述：主要为验证，中文姓名、身份证号、手机号是否匹配一致。
     * @param string $mobile 手机号
     * @param string $usrName 证件姓名
     * @param string $certNo 卡号[身份证]
     */
    public function actionOperator3($usrName, $mobile, $certNo)
    {
        /*$params = [
            'usrName' => '杨松霖', // 证件姓名
            'sensData' => [
                'certNo' => "320311198806185531", // 证件号 只限身份证
                'cardPhone' => "15150001117", //    手机号
            ]
        ];*/
        if ($usrName){}else{
            throw new ErrorException('usrName不能为空', 1075);
        }
        if ($mobile){}else{
            throw new ErrorException('mobile不能为空', 1076);
        }
        if ($certNo){}else{
            throw new ErrorException('certNo不能为空', 1077);
        }
        $sl_check_1025 = SlCheck1025::findOne(['c_name'=>$usrName, 'c_tel'=>$mobile, 'c_card'=>$certNo]);
        if ($sl_check_1025){
            if (time()-$sl_check_1025->c_time>3600*24*30||$sl_check_1025->c_source!=$sl_check_1025::SOURCE_UNIONPAY||$sl_check_1025->perfer_back!='认证/查询成功'){
                $sl_check_1025->c_time = time();
                $sl_check_1025->c_source = $sl_check_1025::SOURCE_UNIONPAY;
            }else{
                return [
                    'sl_check' => $sl_check_1025->toArray(),
                ];
            }
        }else{
            $sl_check_1025 = new SlCheck1025();
            $sl_check_1025->c_name = $usrName;
            $sl_check_1025->c_tel = $mobile;
            $sl_check_1025->c_card = $certNo;
            $sl_check_1025->c_source = $sl_check_1025::SOURCE_UNIONPAY;
            $sl_check_1025->c_time = time();
        }
        $unionpay = new Unionpay();
        $r = $unionpay->send(Config::$b_url, [
//            'mobile' => $mobile,
            'dcType' => '0', // 借贷标志
            'certType' => '01', // 证件类型
            'usrName' => $usrName, // 证件姓名
            'sensData' => [
                'certNo' => $certNo, // 证件号
                'cardPhone' => $mobile, // 卡关联手机号
            ], // 敏感域
        ], [
            'busiType'=>'1025',
        ]);
        $sl_check_1025->perfer_back = $r['_respData']['respMsg'];
        $sl_check_1025->c_orderid = $r['_respData']['orderId'];
        $sl_check_1025->c_post = $r['_respData']['c_post'];
        $sl_check_1025->c_back = $r['_respData']['c_back'];
        if ($sl_check_1025->save()){}else{
//            return $sl_check_1025->getErrors();
            throw new ErrorException("保存失败".var_export($sl_check_1025->getErrors(), true), 1066);
        }
        $_r = array_merge(['sl_check_1025' => $sl_check_1025->toArray()], $r);
        return $_r;
    }

    /**
     * 个人身份证号信用评估
     * @desc 3.6.2《业务编号：1009（个人身份证号信用评估）》功能描述：主要为查询个人身份证号是否命中黑名单的风险。
     * @param string $cardNo 身份证号
     */
    public function actionPersonalIdEvn($certNo)
    {
        /*$params = [
            'sensData' => [
                'certNo' => "320311198806185531", // 证件号
            ]
        ];*/
        if ($certNo){}else{
            throw new ErrorException('certNo不能为空', 1078);
        }
        $sl_check_1009 = SlCheck1009::findOne(['c_card'=>$certNo]);
        if ($sl_check_1009){
            if (!$sl_check_1009->perfer_back){
                $sl_check_1009->c_time = time();
                $sl_check_1009->c_source = $sl_check_1009::SOURCE_UNIONPAY;
            }else{
                return [
                    'sl_check' => $sl_check_1009->toArray(),
                ];
            }
        }else{
            $sl_check_1009 = new SlCheck1009();
            $sl_check_1009->c_card = $certNo;
            $sl_check_1009->c_source = $sl_check_1009::SOURCE_UNIONPAY;
            $sl_check_1009->c_time = time();
        }
        $unionpay = new Unionpay();
        $r = $unionpay->send(Config::$b_url, [
            'sensData' => [
                'certNo' => $certNo, // 证件号
            ], // 敏感域
        ], [
            'busiType'=>'1009',
        ]);
        $x = "";
        if (isset($r['_respData']['hitBadCardHolder'])){
            $x .= $r['_respData']['hitBadCardHolder']?"命中不良持卡人;":"";
            $x .= $r['_respData']['hitEconomicCrime']?"命中经济犯罪;":"";
            $x .= $r['_respData']['hitInvolvedTerrorism']?"命中涉恐人员;":"";
            $x .= $r['_respData']['hitLoseTrust']?"命中失信人员;":"";
            $x .= $r['_respData']['hitTriggerRiskRule']?"命中触犯风险规则;":"";
        }
        $sl_check_1009->perfer_back= $r['_respData']['respMsg'].$x;
        $sl_check_1009->c_orderid = $r['_respData']['orderId'];
        $sl_check_1009->c_post = $r['_respData']['c_post'];
        $sl_check_1009->c_back = $r['_respData']['c_back'];
        if ($sl_check_1009->save()){}else{
//            return $sl_check_1009->getErrors();
            throw new ErrorException("保存失败".var_export($sl_check_1009->getErrors(), true), 1067);
        }
        $_r = array_merge(['sl_check_1009' => $sl_check_1009->toArray()], $r);
        return $_r;
    }

    /**
     * 获取人脸识别3002的认证请求数据
     * @desc 主要为根据手机设备上采集的身份证号，中文姓名，样本照片，验证本人的相似度。
     * @param string $usrName 中文姓名2-64
     * @param string $compareXp 比对照片0-32700
     * @param string $deviceOs 操作系统名称“Android”或者“iOS”
     * @param string $deviceName 机型
     * @param string $certNo 身份证号
     * @param string $bgRetUrl 请求地址
     * @param string $merNo 商户号
     * @param string $b_url 交易类url
     * @param string $orderDate 订单时间
     * @param string $orderId 订单id
     * @param boolean $unRequest 是否直接获取reqData
     */
    public function actionGetFaceRec3002RequestData($usrName, $compareXp, $deviceOs, $deviceName = null, $certNo, $bgRetUrl, $merNo = null, $b_url = null, $orderDate = null, $orderId = null, $unRequest = 1)
    {
        $url = $b_url?$b_url:Config::$b_url;
        $merNo = $merNo?$merNo:Config::$merchant_id;// 商户号
        $reqData = [
            'usrName' => $usrName,
            'compareXp' => $compareXp,
            'deviceOs' => $deviceOs,
//            'deviceName' => $deviceName,
            'bgRetUrl' => $bgRetUrl,
            'sensData' => [
                'certNo' => $certNo, // 证件号
            ], // 敏感域
        ];
        $otherData = [
            'unRequest' => $unRequest,
            'busiType'=>'3002',
            'merNo' => $merNo,
            'orderDate' => $orderDate,
            'orderId' => $orderId,
        ];
//        return [
//            'url' => $url,
//            'reqData' => $reqData,
//            'other_data' => $otherData,
//        ];
        $unionpay = new Unionpay();
        $r = $unionpay->send($url, $reqData, $otherData);
        $log = new Unionpay3002SetLog();
        $log->order_id = $orderId;
        $log->u_name = $usrName;
        $log->id_card = $certNo;
        $log->p_data = serialize(['reqData'=>$reqData, 'otherData'=>$otherData]);
        $log->p_at = time();
        $log->device_name = $deviceName;
        $log->save();
        return $r;
    }

    /**
     * 获取人脸识别3002的认证回调数据获取
     * @desc 主要为根据手机设备上采集的身份证号，中文姓名，样本照片，验证本人的相似度的回调获取。
     * @param string $orderId 订单号
     */
    public function actionGet3002($orderId)
    {
        $data =  \Yii::$app->cache->get('orderId_'.$orderId);
        if (!$data){
            throw new ErrorException("没有回调结果");
        }
        $log = Unionpay3002SetLog::findOne(['order_id' => $data['_respData']['orderId']]);
        if (!$log){
            throw new ErrorException("get3002 没有记录请求");
        }
        $log->last_get_time = time();
        $log->save();
        $data['score'] = $data['_respData']['score'];
        return $data;
    }

    /**
     * 根据身份证号 获取人脸识别3002的最新认证回调数据获取
     * @desc 主要为根据手机设备上采集的身份证号，中文姓名，样本照片，验证本人的相似度的回调获取。
     * @param string $id_card 身份证号
     * @return int status 10:有相似度获取的最新相似度,11:没有该身份证号的请求,12:没有相似度
     */
    public function actionGet3002ByIdCard($id_card)
    {
        $x =  Unionpay3002SetLog::find()->where(['id_card' => $id_card])->orderBy(['score'=>SORT_DESC, 'p_at'=>SORT_DESC])->one();
        if (!$x){
            $_x = new Unionpay3002SetLog();
            $x = $_x->toArray();
            $x['status'] = 11;
            $x['status_msg'] = "没有该身份证号的请求";
            return $x;
        }
        if (!$x->score){
            if (time() - $x->p_at > 300){
                $x = $x->toArray();
                $x['status'] = 12;
                $x['status_msg'] = "没有相似度";
                return $x;
            }else{
                $x = $x->toArray();
                $x['status'] = 13;
                $x['status_msg'] = "等待相似度";
                return $x;
            }
        }
        $x->last_get_time = time();
        $x->save();
        $x = $x->toArray();
        $x['status'] = 10;
        $x['status_msg'] = "有相似度";
        return $x;
    }

    /**
     * 根据订单号获取所有人的实时面签值[app使用]
     * @desc get/post
     * @param string $o_id dyhl_order
     */
    public function actionOrdersGet3002($o_id)
    {
        $out = [];
        $order = Order::findOne(['o_id'=>$o_id]);
        if (!$order){
            return $out;
        }
        foreach ($order->certs as $k => $v){
            $tmp = $v->toArray();
            $id_card = $v->ct_code;
            $tmp['_detail'] = $this->actionGet3002ByIdCard($id_card);
            if ($tmp['_detail'])$out[] = $tmp['_detail'];
        }
        return  $out;
    }
}